<?PHP
        /**
         * @author Cobi Carter
	 * @copyright licensed under GPL as specified http://en.wikipedia.org/wiki/User_talk:ClueBot_Commons/Archives/2010/June#ClueBot_source_and_MediaWiki_SVN
	 * Retreived ~2011-05-15 from http://en.wikipedia.org/wiki/User:ClueBot/Source
         **/
        
        /**
         * This class is designed to provide a simplified interface to cURL which maintains cookies.
         * @author Cobi
         **/
        class http {
                private $ch;
                private $uid;
                public $postfollowredirs;
                public $getfollowredirs;

                /**
                 * Our constructor function.  This just does basic cURL initialization.
                 * @return void
                 **/
                function __construct () {
                        global $proxyhost, $proxyport, $proxytype;
                        $this->ch = curl_init();
                        $this->uid = dechex(rand(0,99999999));
                        curl_setopt($this->ch,CURLOPT_COOKIEJAR,'/tmp/cluewikibot.cookies.'.$this->uid.'.dat');
                        curl_setopt($this->ch,CURLOPT_COOKIEFILE,'/tmp/cluewikibot.cookies.'.$this->uid.'.dat');
                        curl_setopt($this->ch,CURLOPT_MAXCONNECTS,100);
                        curl_setopt($this->ch,CURLOPT_CLOSEPOLICY,CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
                        curl_setopt($this->ch,CURLOPT_USERAGENT,'ClueBot/1.1');
                        if (isset($proxyhost) and isset($proxyport) and ($proxyport != null) and ($proxyhost != null)) {
                                curl_setopt($this->ch,CURLOPT_PROXYTYPE,isset( $proxytype ) ? $proxytype : CURLPROXY_HTTP);
                                curl_setopt($this->ch,CURLOPT_PROXY,$proxyhost);
                                curl_setopt($this->ch,CURLOPT_PROXYPORT,$proxyport);
                        }
                        $this->postfollowredirs = 0;
                        $this->getfollowredirs = 1;
                }

                /**
                 * Post to a URL.
                 * @param $url The URL to post to.
                 * @param $data The post-data to post, should be an array of key => value pairs.
                 * @return Data retrieved from the POST request.
                 **/
                function post ($url,$data) {
                        $time = microtime(1);
                        curl_setopt($this->ch,CURLOPT_URL,$url);
                        curl_setopt($this->ch,CURLOPT_FOLLOWLOCATION,$this->postfollowredirs);
                        curl_setopt($this->ch,CURLOPT_MAXREDIRS,10);
                        curl_setopt($this->ch,CURLOPT_HEADER,0);
                        curl_setopt($this->ch,CURLOPT_RETURNTRANSFER,1);
                        curl_setopt($this->ch,CURLOPT_TIMEOUT,30);
                        curl_setopt($this->ch,CURLOPT_CONNECTTIMEOUT,10);
                        curl_setopt($this->ch,CURLOPT_POST,1);
                        curl_setopt($this->ch,CURLOPT_POSTFIELDS, $data);
                        curl_setopt($this->ch,CURLOPT_HTTPHEADER, array('Expect:'));
                        $data = curl_exec($this->ch);
                        global $logfd; if (!is_resource($logfd)) $logfd = fopen('php://stderr','w'); fwrite($logfd,'POST: '.$url.' ('.(microtime(1) - $time).' s) ('.strlen($data)." b)\n");
                        return $data;
                }

                /**
                 * Get a URL.
                 * @param $url The URL to get.
                 * @return Data retrieved from the GET request.
                 **/
                function get ($url) {
                        $time = microtime(1);
                        curl_setopt($this->ch,CURLOPT_URL,$url);
                        curl_setopt($this->ch,CURLOPT_FOLLOWLOCATION,$this->getfollowredirs);
                        curl_setopt($this->ch,CURLOPT_MAXREDIRS,10);
                        curl_setopt($this->ch,CURLOPT_HEADER,0);
                        curl_setopt($this->ch,CURLOPT_RETURNTRANSFER,1);
                        curl_setopt($this->ch,CURLOPT_TIMEOUT,30);
                        curl_setopt($this->ch,CURLOPT_CONNECTTIMEOUT,10);
                        curl_setopt($this->ch,CURLOPT_HTTPGET,1);
                        $data = curl_exec($this->ch);
                        global $logfd; if (!is_resource($logfd)) $logfd = fopen('php://stderr','w'); fwrite($logfd,'GET: '.$url.' ('.(microtime(1) - $time).' s) ('.strlen($data)." b)\n");
                        return $data;
                }

                /**
                 * Our destructor.  Cleans up cURL and unlinks temporary files.
                 **/
                function __destruct () {
                        curl_close($this->ch);
                        @unlink('/tmp/cluewikibot.cookies.'.$this->uid.'.dat');
                }
        }

        /**
         * This class is a deprecated wrapper class which allows legacy code written for Wikipedia's query.php API to still work with wikipediaapi::.
         **/
        class wikipediaquery {
                private $http;
                private $api;
                public $queryurl = 'http://rappelz.wikia.com/query.php'; //Obsolete, but kept for compatibility purposes.

                /**
                 * This is our constructor.
                 * @return void
                 **/
                function __construct () {
                        global $__wp__http;
                        if (!isset($__wp__http)) {
                                $__wp__http = new http;
                        }
                        $this->http = &$__wp__http;
                        $this->api = new wikipediaapi;
                }

                /**
                 * Reinitializes the queryurl.
                 * @private
                 * @return void
                 **/
                private function checkurl() {
                        $this->api->apiurl = str_replace('query.php','api.php',$this->queryurl);
                }

                /**
                 * Gets the content of a page.
                 * @param $page The wikipedia page to fetch.
                 * @return The wikitext for the page.
                 **/
                function getpage ($page) {
                        $this->checkurl();
                        $ret = $this->api->revisions($page,1,'older',true,null,true,false,false,false);
                        return $ret[0]['*'];
                }

                /**
                 * Gets the page id for a page.
                 * @param $page The wikipedia page to get the id for.
                 * @return The page id of the page.
                 **/
                function getpageid ($page) {
                        $this->checkurl();
                        $ret = $this->api->revisions($page,1,'older',false,null,true,false,false,false);
                        return $ret['pageid'];
                }

                /**
                 * Gets the number of contributions a user has.
                 * @param $user The username for which to get the edit count.
                 * @return The number of contributions the user has.
                 **/
                function contribcount ($user) {
                        $this->checkurl();
                        $ret = $this->api->users($user,1,null,true);
                        if ($ret !== false) return $ret[0]['editcount'];
                        return false;
                }
        }

        /**
         * This class is for interacting with Wikipedia's api.php API.
         **/
        class wikipediaapi {
                private $http;
                private $edittoken;
                private $tokencache;
                private $user, $pass;
                public $apiurl = 'http://rappelz.wikia.com/api.php';

                /**
                 * This is our constructor.
                 * @return void
                 **/
                function __construct () {
                        global $__wp__http;
                        if (!isset($__wp__http)) {
                                $__wp__http = new http;
                        }
                        $this->http = &$__wp__http;
                }

                /**
                 * This function takes a username and password and logs you into wikipedia.
                 * @param $user Username to login as.
                 * @param $pass Password that corrisponds to the username.
                 * @return void
                 **/
                function login ($user,$pass) {
                        $this->user = $user;
                        $this->pass = $pass;
                        $x = unserialize($this->http->post($this->apiurl.'?action=login&format=php',array('lgname' => $user, 'lgpassword' => $pass)));
                        if($x['login']['result'] == 'Success')
                                return true;
                        if($x['login']['result'] == 'NeedToken') {
                                $x = unserialize($this->http->post($this->apiurl.'?action=login&format=php',array('lgname' => $user, 'lgpassword' => $pass, 'lgtoken' => $x['login']['token'])));
                                if($x['login']['result'] == 'Success')
                                        return true;
                        }
                        return false;
                }

                /**
                 * This function returns the edit token.
                 * @return Edit token.
                 **/
                function getedittoken () {
                        $tokens = $this->gettokens('Main Page');
                        if ($tokens['edittoken'] == '') $tokens = $this->gettokens('Main Page',true);
                        $this->edittoken = $tokens['edittoken'];
                        return $tokens['edittoken'];
                }

                /**
                 * This function returns the various tokens for a certain page.
                 * @param $title Page to get the tokens for.
                 * @param $flush Optional - internal use only.  Flushes the token cache.
                 * @return An associative array of tokens for the page.
                 **/
                function gettokens ($title,$flush = false) {
                        if (!is_array($this->tokencache)) $this->tokencache = array();
                        foreach ($this->tokencache as $t => $data) if (time() - $data['timestamp'] > 6*60*60) unset($this->tokencache[$t]);
                        if (isset($this->tokencache[$title]) && (!$flush)) {
                                return $this->tokencache[$title]['tokens'];
                        } else {
                                $tokens = array();
                                $x = $this->http->get($this->apiurl.'?action=query&format=php&prop=info&intoken=edit|delete|protect|move|block|unblock|email&titles='.urlencode($title));
                                $x = unserialize($x);
                                foreach ($x['query']['pages'] as $y) {
                                        $tokens['edittoken'] = (!empty($y['edittoken']) ? $y['edittoken'] : null);
                                        $tokens['deletetoken'] = (!empty($y['deletetoken']) ? $y['deletetoken'] : null);
                                        $tokens['protecttoken'] = (!empty($y['protecttoken']) ? $y['protecttoken'] : null);
                                        $tokens['movetoken'] = (!empty($y['movetoken']) ? $y['movetoken'] : null);
                                        $tokens['blocktoken'] = (!empty($y['blocktoken']) ? $y['blocktoken'] : null);
                                        $tokens['unblocktoken'] = (!empty($y['unblocktoken']) ? $y['unblocktoken'] : null);
                                        $tokens['emailtoken'] = (!empty($y['emailtoken']) ? $y['emailtoken'] : null);
                                        $this->tokencache[$title] = array(
                                                        'timestamp' => time(),
                                                        'tokens' => $tokens
                                                                         );
                                        return $tokens;
                                }
                        }
                }

                /**
                 * This function returns the recent changes for the wiki.
                 * @param $count The number of items to return. (Default 10)
                 * @param $namespace The namespace ID to filter items on. Null for no filtering. (Default null)
                 * @param $dir The direction to pull items.  "older" or "newer".  (Default 'older')
                 * @param $ts The timestamp to start at.  Null for the beginning/end (depending on direction).  (Default null)
                 * @return Associative array of recent changes metadata.
                 **/
                function recentchanges ($count = 10,$namespace = null,$dir = 'older',$ts = null) {
                        $append = '';
                        if ($ts !== null) { $append .= '&rcstart='.urlencode($ts); }
                        $append .= '&rcdir='.urlencode($dir);
                        if ($namespace !== null) { $append .= '&rcnamespace='.urlencode($namespace); }
                        $x = $this->http->get($this->apiurl.'?action=query&list=recentchanges&rcprop=user|comment|flags|timestamp|title|ids|sizes&format=php&rclimit='.$count.$append);
                        $x = unserialize($x);
                        return $x['query']['recentchanges'];
                }

                /**
                 * This function returns search results from Wikipedia's internal search engine.
                 * @param $search The query string to search for.
                 * @param $limit The number of results to return. (Default 10)
                 * @param $offset The number to start at.  (Default 0)
                 * @param $namespace The namespace ID to filter by.  Null means no filtering.  (Default 0)
                 * @param $what What to search, 'text' or 'title'.  (Default 'text')
                 * @param $redirs Whether or not to list redirects.  (Default false)
                 * @return Associative array of search result metadata.
                 **/
                function search ($search,$limit = 10,$offset = 0,$namespace = 0,$what = 'text',$redirs = false) {
                        $append = '';
                        if ($limit != null) $append .= '&srlimit='.urlencode($limit);
                        if ($offset != null) $append .= '&sroffset='.urlencode($offset);
                        if ($namespace != null) $append .= '&srnamespace='.urlencode($namespace);
                        if ($what != null) $append .= '&srwhat='.urlencode($what);
                        if ($redirs == true) $append .= '&srredirects=1';
                        else $append .= '&srredirects=0';
                        $x = $this->http->get($this->apiurl.'?action=query&list=search&format=php&srsearch='.urlencode($search).$append);
                        $x = unserialize($x);
                        return $x['query']['search'];
                }

                /**
                 * Retrieve entries from the WikiLog.
                 * @param $user Username who caused the entry.  Null means anyone.  (Default null)
                 * @param $title Object to which the entry refers.  Null means anything.  (Default null)
                 * @param $limit Number of entries to return.  (Default 50)
                 * @param $type Type of logs.  Null means any type.  (Default null)
                 * @param $start Date to start enumerating logs.  Null means beginning/end depending on $dir.  (Default null)
                 * @param $end Where to stop enumerating logs.  Null means whenever limit is satisfied or there are no more logs.  (Default null)
                 * @param $dir Direction to enumerate logs.  "older" or "newer".  (Default 'older')
                 * @return Associative array of logs metadata.
                 **/
                function logs ($user = null,$title = null,$limit = 50,$type = null,$start = null,$end = null,$dir = 'older') {
                        $append = '';
                        if ($user != null) $append.= '&leuser='.urlencode($user);
                        if ($title != null) $append.= '&letitle='.urlencode($title);
                        if ($limit != null) $append.= '&lelimit='.urlencode($limit);
                        if ($type != null) $append.= '&letype='.urlencode($type);
                        if ($start != null) $append.= '&lestart='.urlencode($start);
                        if ($end != null) $append.= '&leend='.urlencode($end);
                        if ($dir != null) $append.= '&ledir='.urlencode($dir);
                        $x = $this->http->get($this->apiurl.'?action=query&format=php&list=logevents&leprop=ids|title|type|user|timestamp|comment|details'.$append);
                        $x = unserialize($x);
                        return $x['query']['logevents'];
                }

                /**
                 * Retrieves metadata about a user's contributions.
                 * @param $user Username whose contributions we want to retrieve.
                 * @param $count Number of entries to return.  (Default 50)
                 * @param[in,out] $continue Where to continue enumerating if part of a larger, split request.  This is filled with the next logical continuation value.  (Default null)
                 * @param $dir Which direction to enumerate from, "older" or "newer".  (Default 'older')
                 * @return Associative array of contributions metadata.
                 **/
                function usercontribs ($user,$count = 50,&$continue = null,$dir = 'older') {
                        if ($continue != null) {
                                $append = '&ucstart='.urlencode($continue);
                        } else {
                                $append = '';
                        }
                        $x = $this->http->get($this->apiurl.'?action=query&format=php&list=usercontribs&ucuser='.urlencode($user).'&uclimit='.urlencode($count).'&ucdir='.urlencode($dir).$append);
                        $x = unserialize($x);
                        $continue = $x['query-continue']['usercontribs']['ucstart'];
                        return $x['query']['usercontribs'];
                }

                /**
                 * Returns revision data (meta and/or actual).
                 * @param $page Page for which to return revision data for.
                 * @param $count Number of revisions to return. (Default 1)
                 * @param $dir Direction to start enumerating multiple revisions from, "older" or "newer". (Default 'older')
                 * @param $content Whether to return actual revision content, true or false.  (Default false)
                 * @param $revid Revision ID to start at.  (Default null)
                 * @param $wait Whether or not to wait a few seconds for the specific revision to become available.  (Default true)
                 * @param $getrbtok Whether or not to retrieve a rollback token for the revision.  (Default false)
                 * @param $dieonerror Whether or not to kill the process with an error if an error occurs.  (Default false)
                 * @param $redirects Whether or not to follow redirects.  (Default false)
                 * @return Associative array of revision data.
                 **/
                function revisions ($page,$count = 1,$dir = 'older',$content = false,$revid = null,$wait = true,$getrbtok = false,$dieonerror = true,$redirects = false) {
			$qs = $this->apiurl.'?action=query&prop=revisions&titles='.urlencode($page).'&rvlimit='.urlencode($count).'&rvprop=timestamp|ids|user|comment'.(($content)?'|content':'').'&format=php&meta=userinfo&rvdir='.urlencode($dir).(($revid !== null)?'&rvstartid='.urlencode($revid):'').(($getrbtok == true)?'&rvtoken=rollback':'').(($redirects == true)?'&redirects':'');
                        $x = $this->http->get($qs);
                        $x = unserialize($x);
                        if ($revid !== null) {
                                $found = false;
                                if (!isset($x['query']['pages']) or !is_array($x['query']['pages'])) {
                                        if ($dieonerror == true) die('No such page.'."\n");
                                        else return false;
                                }
                                foreach ($x['query']['pages'] as $data) {
                                        if (!isset($data['revisions']) or !is_array($data['revisions'])) {
                                                if ($dieonerror == true) die('No such page.'."\n");
                                                else return false;
                                        }
                                        foreach ($data['revisions'] as $data2) if ($data2['revid'] == $revid) $found = true;
                                        unset($data,$data2);
                                        break;
                                }

                                if ($found == false) {
                                        if ($wait == true) {
                                                sleep(1);
                                                return $this->revisions($page,$count,$dir,$content,$revid,false,$getrbtok,$dieonerror);
                                        } else {
                                                if ($dieonerror == true) die('Revision error.'."\n");
                                        }
                                }
                        }
                        foreach ($x['query']['pages'] as $key => $data) {
                                $data['revisions']['ns'] = $data['ns'];
                                $data['revisions']['title'] = $data['title'];
                                $data['revisions']['currentuser'] = $x['query']['userinfo']['name'];
//                              $data['revisions']['currentuser'] = $x['query']['userinfo']['currentuser']['name'];
				if(isset($x['query-continue']['revisions']['rvstartid'])){
					$data['revisions']['continue'] = $x['query-continue']['revisions']['rvstartid'];
				}
                                $data['revisions']['pageid'] = $key;
                                return $data['revisions'];
                        }
                }

                /**
                 * Enumerates user metadata.
                 * @param $start The username to start enumerating from.  Null means from the beginning.  (Default null)
                 * @param $limit The number of users to enumerate.  (Default 1)
                 * @param $group The usergroup to filter by.  Null means no filtering.  (Default null)
                 * @param $requirestart Whether or not to require that $start be a valid username.  (Default false)
                 * @param[out] $continue This is filled with the name to continue from next query.  (Default null)
                 * @return Associative array of user metadata.
                 **/
                function users ($start = null,$limit = 1,$group = null,$requirestart = false,&$continue = null) {
                        $append = '';
                        if ($start != null) $append .= '&aufrom='.urlencode($start);
                        if ($group != null) $append .= '&augroup='.urlencode($group);
                        $x = $this->http->get($this->apiurl.'?action=query&list=allusers&format=php&auprop=blockinfo|editcount|registration|groups&aulimit='.urlencode($limit).$append);
                        $x = unserialize($x);
                        $continue = $x['query-continue']['allusers']['aufrom'];
                        if (($requirestart == true) and ($x['query']['allusers'][0]['name'] != $start)) return false;
                        return $x['query']['allusers'];
                }

                /**
                 * Get members of a category.
                 * @param $category Category to enumerate from.
                 * @param $count Number of members to enumerate.  (Default 500)
                 * @param[in,out] $continue Where to continue enumerating from.  This is automatically filled in when run.  (Default null)
                 * @return Associative array of category member metadata.
                 **/
                function categorymembers ($category,$count = 500,&$continue = null) {
                        if ($continue != null) {
                                $append = '&cmcontinue='.urlencode($continue);
                        } else {
                                $append = '';
                        }
                        $category = 'Category:'.str_ireplace('category:','',$category);
                        $x = $this->http->get($this->apiurl.'?action=query&list=categorymembers&cmtitle='.urlencode($category).'&format=php&cmlimit='.$count.$append);
                        $y = unserialize($x);
/*			if(!is_array($y)) { 
				print "error content recieved:========= \n";
				print_r($x) ;
				print "error content end:=========\n";
			}
*/
/*print("<pre>");
print_r($x);
print("</pre>");
*/			
			if(isset($y['query-continue']['categorymembers']['cmcontinue']))
				$continue = $y['query-continue']['categorymembers']['cmcontinue'];
                        return $y['query']['categorymembers'];
                }

                /**
                 * Enumerate all categories.
                 * @param[in,out] $start Where to start enumerating.  This is updated automatically with the value to continue from.  (Default null)
                 * @param $limit Number of categories to enumerate.  (Default 50)
                 * @param $dir Direction to enumerate in.  'ascending' or 'descending'.  (Default 'ascending')
                 * @param $prefix Only enumerate categories with this prefix.  (Default null)
                 * @return Associative array of category list metadata.
                 **/
                function listcategories (&$start = null,$limit = 50,$dir = 'ascending',$prefix = null) {
                        $append = '';
                        if ($start != null) $append .= '&acfrom='.urlencode($start);
                        if ($limit != null) $append .= '&aclimit='.urlencode($limit);
                        if ($dir != null) $append .= '&acdir='.urlencode($dir);
                        if ($prefix != null) $append .= '&acprefix='.urlencode($prefix);

                        $x = $this->http->get($this->apiurl.'?action=query&list=allcategories&acprop=size&format=php'.$append);
                        $x = unserialize($x);

                        $start = $x['query-continue']['allcategories']['acfrom'];

                        return $x['query']['allcategories'];
                }

                /**
                 * Enumerate all backlinks to a page.
                 * @param $page Page to search for backlinks to.
                 * @param $count Number of backlinks to list.  (Default 500)
                 * @param[in,out] $continue Where to start enumerating from.  This is automatically filled in.  (Default null)
                 * @param $filter Whether or not to include redirects.  Acceptible values are 'all', 'redirects', and 'nonredirects'.  (Default null)
                 * @return Associative array of backlink metadata.
                 **/
                function backlinks ($page,$count = 500,&$continue = null,$filter = null) {
                        if ($continue != null) {
                                $append = '&blcontinue='.urlencode($continue);
                        } else {
                                $append = '';
                        }
                        if ($filter != null) {
                                $append .= '&blfilterredir='.urlencode($filter);
                        }

                        $x = $this->http->get($this->apiurl.'?action=query&list=backlinks&bltitle='.urlencode($page).'&format=php&bllimit='.$count.$append);
                        $x = unserialize($x);
                        $continue = $x['query-continue']['backlinks']['blcontinue'];
                        return $x['query']['backlinks'];
                }

                /**
                 * Gets a list of transcludes embedded in a page.
                 * @param $page Page to look for transcludes in.
                 * @param $count Number of transcludes to list.  (Default 500)
                 * @param[in,out] $continue Where to start enumerating from.  This is automatically filled in.  (Default null)
                 * @return Associative array of transclude metadata.
                 **/
                function embeddedin ($page,$count = 500,&$continue = null) {
                        if ($continue != null) {
                                $append = '&eicontinue='.urlencode($continue);
                        } else {
                                $append = '';
                        }
                        $x = $this->http->get($this->apiurl.'?action=query&list=embeddedin&eititle='.urlencode($page).'&format=php&eilimit='.$count.$append);
                        $x = unserialize($x);
                        $continue = $x['query-continue']['embeddedin']['eicontinue'];
                        return $x['query']['embeddedin'];
                }

                /**
                 * Gets a list of pages with a common prefix.
                 * @param $prefix Common prefix to search for.
                 * @param $namespace Numeric namespace to filter on.  (Default 0)
                 * @param $count Number of pages to list.  (Default 500)
                 * @param[in,out] $continue Where to start enumerating from.  This is automatically filled in.  (Default null)
                 * @return Associative array of page metadata.
                 **/
                function listprefix ($prefix,$namespace = 0,$count = 500,&$continue = null) {
                        $append = '&apnamespace='.urlencode($namespace);
                        if ($continue != null) {
                                $append .= '&apfrom='.urlencode($continue);
                        }
                        $x = $this->http->get($this->apiurl.'?action=query&list=allpages&apprefix='.urlencode($prefix).'&format=php&aplimit='.$count.$append);
                        $x = unserialize($x);
                        $continue = $x['query-continue']['allpages']['apfrom'];
                        return $x['query']['allpages'];
                }

                /**
                 * Edits a page.
                 * @param $page Page name to edit.
                 * @param $data Data to post to page.
                 * @param $summary Edit summary to use.
                 * @param $minor Whether or not to mark edit as minor.  (Default false)
                 * @param $bot Whether or not to mark edit as a bot edit.  (Default true)
                 * @param $wpStarttime Time in MW TS format of beginning of edit.  (Default now)
                 * @param $wpEdittime Time in MW TS format of last edit to that page.  (Default correct)
                 * @return boolean True on success, false on failure.
                 **/
                function edit ($page,$data,$summary = '',$minor = false,$bot = true,$wpStarttime = null,$wpEdittime = null,$checkrun = true) {
                        global $run;//, $user;

                        $wpq = new wikipediaquery; $wpq->queryurl = str_replace('api.php','query.php',$this->apiurl);

                        if ($checkrun == true)
                                if (!preg_match('/(yes|enable|true)/iS',((isset($run))?$run:$wpq->getpage('User:'.$this->user.'/Run'))))
                                        return false; /* Check /Run page */

                        $params = Array(
                                'action' => 'edit',
                                'format' => 'php',
                                'assert' => 'bot',
                                'title' => $page,
                                'text' => $data,
                                'token' => $this->getedittoken(),
                                'summary' => $summary,
                                ($minor?'minor':'notminor') => '1',
                                ($bot?'bot':'notbot') => '1'
                        );

                        if ($wpStarttime !== null) $params['starttimestamp'] = $wpStarttime;
                        if ($wpEdittime !== null) $params['basetimestamp'] = $wpEdittime;

                        $x = $this->http->post($this->apiurl,$params);
                        $x = unserialize($x);
                        var_export($x);
                        if ($x['edit']['result'] == 'Success') return true;
                        if ($x['error']['code'] == 'badtoken') {
                                if($this->login($this->user,$this->pass)) {
                                        $this->gettokens('Main Page',true);
                                        return $this->edit($page,$data,$summary,$minor,$bot,$wpStarttime,$wpEdittime,$checkrun);
                                } else
                                        return false;
                        }
                        else return false;
                }

                /**
                 * Moves a page.
                 * @param $old Name of page to move.
                 * @param $new New page title.
                 * @param $reason Move summary to use.
                 * @return void
                 **/
                function move ($old,$new,$reason) {
                        $tokens = $this->gettokens($old);
                        $params = array(
                                'action' => 'move',
                                'format' => 'php',
                                'from' => $old,
                                'to' => $new,
                                'token' => $tokens['movetoken'],
                                'reason' => $reason
                        );

                        $x = $this->http->post($this->apiurl,$params);
                        $x = unserialize($x);
                        var_export($x);
                }

                /**
                 * Rollback an edit.
                 * @param $title Title of page to rollback.
                 * @param $user Username of last edit to the page to rollback.
                 * @param $reason Edit summary to use for rollback.
                 * @param $token Rollback token.  If not given, it will be fetched.  (Default null)
                 * @return void
                 **/
                function rollback ($title,$user,$reason,$token = null) {
                        if (($token == null) or ($token == '')) {
                                $token = $this->revisions($title,1,'older',false,null,true,true);
                                print_r($token);
                                if ($token[0]['user'] == $user) {
                                        $token = $token[0]['rollbacktoken'];
                                } else {
                                        return false;
                                }
                        }
                        $params = array(
                                'action' => 'rollback',
                                'format' => 'php',
                                'title' => $title,
                                'user' => $user,
                                'summary' => $reason,
                                'token' => $token,
                                'markbot' => 0
                        );

                        echo 'Posting to API: ';
                        var_export($params);
                        
                        $x = $this->http->post($this->apiurl,$params);
                        $x = unserialize($x);
                        var_export($x);
                        return ( isset($x['rollback']['summary']) and isset( $x[ 'rollback' ][ 'revid' ] ) and $x[ 'rollback' ][ 'revid' ] )
                                ? true
                                : false;
                }
		
		function siteinfo ($replace_apiurl = null, $statistics) {
			$url = !empty($replace_apiurl) ? $replace_apiurl : $this->apiurl;
			// $params = array();
			// $params['action'] = 'query';
			// $params['meta'] = 'siteinfo';
			// $params['format'] = 'xml';
			// $params['siprop'] = 'general' . (!empty($statistics)?'|statistics':'');
			$qs = $url.'?action=query&meta=siteinfo&format=php&siprop=general'.(!empty($statistics)?"|statistics":"");
                        $x = $this->http->get($qs);
                        //$x = $this->http->post($url, $params);
			//print_r($qs);
			//print_r($x);
                        $x = unserialize($x);
			return $x['query'];
		}
        }

        /**
         * This class is for interacting with Wikipedia's browser interface, index.php.
         * Many of these functions are deprecated.
         **/
        class wikipediaindex {
                private $http;
                public $indexurl = 'http://rappelz.wikia.com/index.php';
                private $postinterval = 0;
                private $lastpost;
                private $edittoken;

                /**
                 * This is our constructor.
                 * @return void
                 **/
                function __construct () {
                        global $__wp__http;
                        if (!isset($__wp__http)) {
                                $__wp__http = new http;
                        }
                        $this->http = &$__wp__http;
                }

                /**
                 * Post data to a page, nicely.
                 * @param $page Page title.
                 * @param $data Data to post to page.
                 * @param $summery Edit summary.  (Default '')
                 * @param $minor Whether to mark edit as minor.  (Default false)
                 * @param $rv Revision data.  If not given, it will be fetched.  (Default null)
                 * @param $bot Whether to mark edit as bot.  (Default true)
                 * @return HTML data from the page.
                 * @deprecated
                 * @see wikipediaapi::edit
                 **/
                function post ($page,$data,$summery = '',$minor = false,$rv = null,$bot = true) {
                        global $user;
                        global $maxlag;
                        global $irc;
                        global $irctechchannel;
                        global $run;
                        global $maxlagkeepgoing;

                        $wpq = new wikipediaquery; $wpq->queryurl = str_replace('index.php','query.php',$this->indexurl);
                        $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl);

                        if ((!$this->edittoken) or ($this->edittoken == '')) $this->edittoken = $wpapi->getedittoken();
                        if ($rv == null) $rv = $wpapi->revisions($page,1,'older',true);
                        if (!$rv[0]['*']) $rv[0]['*'] = $wpq->getpage($page);

                        //Fake the edit form.
                        $now = gmdate('YmdHis', time());
                        $token = htmlspecialchars($this->edittoken);
                        $tmp = date_parse($rv[0]['timestamp']);
                        $edittime = gmdate('YmdHis', gmmktime($tmp['hour'],$tmp['minute'],$tmp['second'],$tmp['month'],$tmp['day'],$tmp['year']));
                        $html = "<input type='hidden' value=\"{$now}\" name=\"wpStarttime\" />\n";
                        $html.= "<input type='hidden' value=\"{$edittime}\" name=\"wpEdittime\" />\n";
                        $html.= "<input type='hidden' value=\"{$token}\" name=\"wpEditToken\" />\n";
                        $html.= '<input name="wpAutoSummary" type="hidden" value="'.md5('').'" />'."\n";

                        if (preg_match('/'.preg_quote('{{nobots}}','/').'/iS',$rv[0]['*'])) { return false; }           /* Honor the bots flags */
                        if (preg_match('/'.preg_quote('{{bots|allow=none}}','/').'/iS',$rv[0]['*'])) { return false; }
                        if (preg_match('/'.preg_quote('{{bots|deny=all}}','/').'/iS',$rv[0]['*'])) { return false; }
                        if (preg_match('/'.preg_quote('{{bots|deny=','/').'(.*)'.preg_quote('}}','/').'/iS',$rv[0]['*'],$m)) { if (in_array(explode(',',$m[1]),$user)) { return false; } } /* /Honor the bots flags */
                        if (!preg_match('/'.preg_quote($user,'/').'/iS',$rv['currentuser'])) { return false; } /* We need to be logged in */
//                      if (preg_match('/'.preg_quote('You have new messages','/').'/iS',$rv[0]['*'])) { return false; } /* Check talk page */
                        if (!preg_match('/(yes|enable|true)/iS',((isset($run))?$run:$wpq->getpage('User:'.$user.'/Run')))) { return false; } /* Check /Run page */

                        $x = $this->forcepost($page,$data,$summery,$minor,$html,$maxlag,$maxlagkeepgoing,$bot); /* Go ahead and post. */
                        $this->lastpost = time();
                        return $x;
                }

                /**
                 * Post data to a page.
                 * @param $page Page title.
                 * @param $data Data to post to page.
                 * @param $summery Edit summary.  (Default '')
                 * @param $minor Whether to mark edit as minor.  (Default false)
                 * @param $edithtml HTML from the edit form.  If not given, it will be fetched.  (Default null)
                 * @param $maxlag Maxlag for posting.  (Default null)
                 * @param $mlkg Whether to keep going after encountering a maxlag error and sleeping or not.  (Default null)
                 * @param $bot Whether to mark edit as bot.  (Default true)
                 * @return HTML data from the page.
                 * @deprecated
                 * @see wikipediaapi::edit
                 **/
                function forcepost ($page,$data,$summery = '',$minor = false,$edithtml = null,$maxlag = null,$mlkg = null,$bot = true) {
                        $post['wpSection'] = '';
                        $post['wpScrolltop'] = '';
                        if ($minor == true) { $post['wpMinoredit'] = 1; }
                        $post['wpTextbox1'] = $data;
                        $post['wpSummary'] = $summery;
                        if ($edithtml == null) {
                                $html = $this->http->get($this->indexurl.'?title='.urlencode($page).'&action=edit');
                        } else {
                                $html = $edithtml;
                        }
                        preg_match('|\<input type\=\\\'hidden\\\' value\=\"(.*)\" name\=\"wpStarttime\" /\>|U',$html,$m);
                        $post['wpStarttime'] = $m[1];
                        preg_match('|\<input type\=\\\'hidden\\\' value\=\"(.*)\" name\=\"wpEdittime\" /\>|U',$html,$m);
                        $post['wpEdittime'] = $m[1];
                        preg_match('|\<input type\=\\\'hidden\\\' value\=\"(.*)\" name\=\"wpEditToken\" /\>|U',$html,$m);
                        $post['wpEditToken'] = $m[1];
                        preg_match('|\<input name\=\"wpAutoSummary\" type\=\"hidden\" value\=\"(.*)\" /\>|U',$html,$m);
                        $post['wpAutoSummary'] = $m[1];
                        if ($maxlag != null) {
                                $x = $this->http->post($this->indexurl.'?title='.urlencode($page).'&action=submit&maxlag='.urlencode($maxlag).'&bot='.(($bot == true)?'1':'0'),$post);
                                if (preg_match('/Waiting for ([^ ]*): ([0-9.-]+) seconds lagged/S',$x,$lagged)) {
                                        global $irc;
                                        if (is_resource($irc)) {
                                                global $irctechchannel;
                                                foreach(explode(',',$irctechchannel) as $y) {
                                                        fwrite($irc,'PRIVMSG '.$y.' :'.$lagged[1].' is lagged out by '.$lagged[2].' seconds. ('.$lagged[0].')'."\n");
                                                }
                                        }
                                        sleep(10);
                                        if ($mlkg != true) { return false; }
                                        else { $x = $this->http->post($this->indexurl.'?title='.urlencode($page).'&action=submit&bot='.(($bot == true)?'1':'0'),$post); }
                                }
                                return $x;
                        } else {
                                return $this->http->post($this->indexurl.'?title='.urlencode($page).'&action=submit&bot='.(($bot == true)?'1':'0'),$post);
                        }
                }

                /**
                 * Get a diff.
                 * @param $title Page title to get the diff of.
                 * @param $oldid Old revision ID.
                 * @param $id New revision ID.
                 * @param $wait Whether or not to wait for the diff to become available.  (Default true)
                 * @return Array of added data, removed data, and a rollback token if one was fetchable.
                 **/
                function diff ($title,$oldid,$id,$wait = true) {
                        $deleted = '';
                        $added = '';

                        $html = $this->http->get($this->indexurl.'?title='.urlencode($title).'&action=render&diff='.urlencode($id).'&oldid='.urlencode($oldid).'&diffonly=1');

                        if (preg_match_all('/\&amp\;(oldid\=)(\d*)\\\'\>(Revision as of|Current revision as of)/USs', $html, $m, PREG_SET_ORDER)) {
                                //print_r($m);
                                if ((($oldid != $m[0][2]) and (is_numeric($oldid))) or (($id != $m[1][2]) and (is_numeric($id)))) {
                                        if ($wait == true) {
                                                sleep(1);
                                                return $this->diff($title,$oldid,$id,false);
                                        } else {
                                                echo 'OLDID as detected: '.$m[0][2].' Wanted: '.$oldid."\n";
                                                echo 'NEWID as detected: '.$m[1][2].' Wanted: '.$id."\n";
                                                echo $html;
                                                die('Revision error.'."\n");
                                        }
                                }
                        }
                        
                        if (preg_match_all('/\<td class\=(\"|\\\')diff-addedline\1\>\<div\>(.*)\<\/div\>\<\/td\>/USs', $html, $m, PREG_SET_ORDER)) {
                                //print_r($m);
                                foreach ($m as $x) {
                                        $added .= htmlspecialchars_decode(strip_tags($x[2]))."\n";
                                }
                        }

                        if (preg_match_all('/\<td class\=(\"|\\\')diff-deletedline\1\>\<div\>(.*)\<\/div\>\<\/td\>/USs', $html, $m, PREG_SET_ORDER)) {
                                //print_r($m);
                                foreach ($m as $x) {
                                        $deleted .= htmlspecialchars_decode(strip_tags($x[2]))."\n";
                                }
                        }

                        //echo $added."\n".$deleted."\n";

                        if (preg_match('/action\=rollback\&amp\;from\=.*\&amp\;token\=(.*)\"/US', $html, $m)) {
                                $rbtoken = $m[1];
                                $rbtoken = urldecode($rbtoken);
//                              echo 'rbtoken: '.$rbtoken.' -- '; print_r($m); echo "\n\n";
                                return array($added,$deleted,$rbtoken);
                        }

                        return array($added,$deleted);
                }

                /**
                 * Rollback an edit.
                 * @param $title Page title to rollback.
                 * @param $user Username of last edit to the page to rollback.
                 * @param $reason Reason to rollback.  If null, default is generated.  (Default null)
                 * @param $token Rollback token to use.  If null, it is fetched.  (Default null)
                 * @param $bot Whether or not to mark as bot.  (Default true)
                 * @return HTML or false if failure.
                 * @deprecated
                 * @see wikipediaapi::rollback
                 **/
                function rollback ($title,$user,$reason = null,$token = null,$bot = true) {
                        if (($token == null) or (!$token)) {
                                $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl);
                                $token = $wpapi->revisions($title,1,'older',false,null,true,true);                           
                                if ($token[0]['user'] == $user) {
//                                      echo 'Token: '; print_r($token); echo "\n\n";
                                        $token = $token[0]['rollbacktoken'];
                                } else {
                                        return false;
                                }
                        }
                        $x = $this->http->get($this->indexurl.'?title='.urlencode($title).'&action=rollback&from='.urlencode($user).'&token='.urlencode($token).(($reason != null)?'&summary='.urlencode($reason):'').'&bot='.(($bot == true)?'1':'0'));
                        global $logfd; if (!is_resource($logfd)) $logfd = fopen('php://stderr','w'); fwrite($logfd,'Rollback return: '.$x."\n");
                        if (!preg_match('/action complete/iS',$x)) return false;
                        return $x;
                }

                /**
                 * Move a page.
                 * @param $old Page title to move.
                 * @param $new New title to move to.
                 * @param $reason Move page summary.
                 * @return HTML page.
                 * @deprecated
                 * @see wikipediaapi::move
                 **/
                function move ($old,$new,$reason) {
                        $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl);
                        if ((!$this->edittoken) or ($this->edittoken == '')) $this->edittoken = $wpapi->getedittoken();

                        $token = htmlspecialchars($this->edittoken);

                        $post = array
                                (
                                        'wpOldTitle'    => $old,
                                        'wpNewTitle'    => $new,
                                        'wpReason'      => $reason,
                                        'wpWatch'       => '0',
                                        'wpEditToken'   => $token,
                                        'wpMove'        => 'Move page'
                                );
                        return $this->http->post($this->indexurl.'?title=Special:Movepage&action=submit',$post);
                }

                /**
                 * Uploads a file.
                 * @param $page Name of page on the wiki to upload as.
                 * @param $file Name of local file to upload.
                 * @param $desc Content of the file description page.
                 * @return HTML content.
                 **/
                function upload ($page,$file,$desc) {
                        $post = array
                                (
                                        'wpUploadFile'          => '@'.$file,
                                        'wpSourceType'          => 'file',
                                        'wpDestFile'            => $page,
                                        'wpUploadDescription'   => $desc,
                                        'wpLicense'             => '',
                                        'wpWatchthis'           => '0',
                                        'wpIgnoreWarning'       => '1',
                                        'wpUpload'              => 'Upload file'
                                );
                        return $this->http->post($this->indexurl.'?title=Special:Upload&action=submit',$post);
                }

                /**
                 * Check if a user has email enabled.
                 * @param $user Username to check whether or not the user has email enabled.
                 * @return True or false depending on whether or not the user has email enabled.
                 **/
                function hasemail ($user) {
                        $tmp = $this->http->get($this->indexurl.'?title=Special:EmailUser&target='.urlencode($user));
                        if (stripos($tmp,"No e-mail address") !== false) return false;
                        return true;
                }

                /**
                 * Sends an email to a user.
                 * @param $user Username to send email to.
                 * @param $subject Subject of email to send.
                 * @param $body Body of email to send.
                 * @return HTML content.
                 **/
                function email ($user,$subject,$body) {
                        $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl);
                        if ((!$this->edittoken) or ($this->edittoken == '')) $this->edittoken = $wpapi->getedittoken();

                        $post = array
                                (
                                        'wpSubject'     => $subject,
                                        'wpText'        => $body,
                                        'wpCCMe'        => 0,
                                        'wpSend'        => 'Send',
                                        'wpEditToken'   => $this->edittoken
                                );

                        return $this->http->post($this->indexurl.'?title=Special:EmailUser&target='.urlencode($user).'&action=submit',$post);
                }
        }
?>
